﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace hse_2013_272_lines
{
    public class CurrentShape
    {
        // Если придумается лучший способ хранить форму/цвета фигуры, то заменим.
        public Block[,] shape { get; private set; }

        // Вопрос на повестке дня: будут ли координаты закрытыми свойствами, изменяемыми методами а-ля MoveLeft, MoveRight, MoveDown, Drop, или же они будут публичными, а вся логика перемещения будет в обработчиках событий?
        //Я сделала открытыми пока, чтобы что-то писать
        //Просьба! Пусть х и у будут координатами левого нижнего края, ок?

        public int x;
        public int y;

        public CurrentShape Rotate()
        {
            int sizeX = shape.GetLength(0);
            int sizeY = shape.GetLength(1);

            Block[,] newShape = new Block[sizeY, sizeX];
            for (int i = 0; i < sizeX; i++)
            {
                for (int j = 0; j < sizeY; j++)
                {
                    newShape[sizeY - j - 1, i] = shape[i, j];
                }
            }
            CurrentShape newCurShape = new CurrentShape(this);
            newCurShape.shape = newShape;
            return newCurShape;
        }

        public void Draw(Graphics g)
        {
            // Физический размер блока и координаты начала поля в объекте g. Где бы их объявить, чтобы получилось красиво?
            const int size = 40;
            const int offsetX = 60;
            const int offsetY = 30;

            for (int i = 0; i < shape.GetLength(0); i++)
                for (int j = 0; j < shape.GetLength(1); j++)
                    if (j + y - shape.GetLength(1) + 1 >= 0)
                        shape[i, j].Draw(g, offsetX + size * (i + x), offsetY + size * (j + y - shape.GetLength(1) + 1));
        }

        // Конструктор копии фигуры
        public CurrentShape(CurrentShape currentShape)
        {
            this.shape = new Block[currentShape.shape.GetLength(0), currentShape.shape.GetLength(1)];
            for (
                int i = 0; i < currentShape.shape.GetLength(0); i++)
                for (int j = 0; j < currentShape.shape.GetLength(1); j++)
                {
                    this.shape[i, j] = currentShape.shape[i, j];
                }
            this.x = currentShape.x;
            this.y = currentShape.y;
        }

        // Вспомогательный конструктор для упрощения описания базового набора фигур
        CurrentShape(int coordX, int coordY, int sizeX, int sizeY, Block block)
        {
            this.x = coordX;
            this.y = coordY;

            this.shape = new Block[sizeX, sizeY];
            for (int i = 0; i < sizeX; i++)
                for (int j = 0; j < sizeY; j++)
                    shape[i, j] = block;
        }


        static CurrentShape()
        {
            L = new CurrentShape(4, 0, 2, 3, Block.Orange);
            L.shape[1, 0] = Block.Empty;
            L.shape[1, 1] = Block.Empty;

            J = new CurrentShape(4, 0, 2, 3, Block.Blue);
            J.shape[0, 0] = Block.Empty;
            J.shape[0, 1] = Block.Empty;

            I = new CurrentShape(4, 0, 1, 4, Block.Cyan);

            O = new CurrentShape(4, 0, 2, 2, Block.Yellow);

            T = new CurrentShape(4, 0, 2, 3, Block.Magenta);
            T.shape[0, 0] = Block.Empty;
            T.shape[0, 2] = Block.Empty;

            Z = new CurrentShape(4, 0, 2, 3, Block.Red);
            Z.shape[0, 0] = Block.Empty;
            Z.shape[1, 2] = Block.Empty;

            S = new CurrentShape(4, 0, 2, 3, Block.Green);
            S.shape[1, 0] = Block.Empty;
            S.shape[0, 2] = Block.Empty;

            shapes = new CurrentShape[] { L, J, I, O, T, Z, S, };
        }


        //Массив стандартных фигур
        public static CurrentShape[] shapes;

        static CurrentShape L;
        static CurrentShape J;
        static CurrentShape I;
        static CurrentShape O;
        static CurrentShape T;
        static CurrentShape Z;
        static CurrentShape S;

        // Немножко шаманства с хардкодом для отрисовки следующей фигуры.
        public void DrawNext(Graphics g)
        {
            const int size = 40;
            const int offsetX = 380;
            const int offsetY = 290;

            for (int i = 0; i < 3; i++)
                g.DrawLine(Pens.White, new Point(offsetX - 5 + size * (i + 4), 165), new Point(offsetX - 5 + size * (i + 4), 325));
            for (int j = 0; j < 5; j++)
                g.DrawLine(Pens.White, new Point(55 + 480, offsetY - 5 + size * (j - 3)), new Point(55 + 480 + 80, offsetY - 5 + size * (j - 3)));


            for (int i = 0; i < shape.GetLength(0); i++)
                for (int j = 0; j < shape.GetLength(1); j++)
                    shape[i, j].Draw(g, offsetX + size * (i + x), offsetY + size * (j + y - shape.GetLength(1) + 1));
        }
    }
}
